package com.cet;

import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FunctionDemo {

    public static void main(String[] args) {

        Supplier<String> supplier = () -> "42";

        System.out.println(supplier.get());

        Predicate<String> isNumber = str -> str.matches("-?\\d+(\\.\\d+)?");
        System.out.println(isNumber.test("42"));

        Function<String, Integer> tranStringToInt = Integer::parseInt;
        System.out.println(tranStringToInt.apply("42"));

        Consumer<Integer> printer = integer -> {
            if (integer % 2 == 0) {
                System.out.println(integer + "是偶数");
            } else {
                System.out.println(integer + "是奇数");
            }
        };

        // 使用以上函数式接口组合判断字符是奇数还是偶数

        Runnable illegalInput = () -> System.out.println("illegal input");

        myMethod(isNumber, supplier, printer, tranStringToInt, illegalInput);

        List<Person> list = List.of(
                new Person("Lei Hot", "male", 18),
                new Person("Mike Smith", "male", 19),
                new Person("Jack Hot", "female", 20),
                new Person("Xiao Hai","female", 15),
                new Person("Mike Smith", "male", 19));

        System.out.println(list.stream().collect(Collectors.groupingBy(Person::getGender, Collectors.counting())));

        list.stream()
                .filter(person -> person.getAge() > 18)
                .limit(2)
                .peek(System.out::println)
                .map(Person::getName)
                .sorted(String::compareTo)
                .flatMap(item -> {
                    String[] s = item.split(" ");
                    return Arrays.stream(s);
                })
                .forEach(System.out::println);
    }

    private static void myMethod(
            Predicate<String> isNumber,
            Supplier<String> supplier,
            Consumer<Integer> printer,
            Function<String, Integer> tranStringToInt,
            Runnable errorLogPrinter) {
        if (isNumber.test(supplier.get())) {
            printer.accept(tranStringToInt.apply(supplier.get()));
        } else {
            errorLogPrinter.run();
        }
    }
}


class Person{

    private String name;
    private String gender;
    private int age;

    public Person(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name) && Objects.equals(gender, person.gender);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, gender, age);
    }
}
